package org.chen.ctrip.service.impl;// CrawlerTaskServiceImpl.java
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.chen.common.ctrip.crawler.CrawlResult;
import org.chen.common.ctrip.crawler.CrawlerExecutionResult;
import org.chen.common.ctrip.crawler.CrawlerTask;
import org.chen.common.ctrip.crawler.CrawlerTaskLog;
import org.chen.ctrip.mapper.CrawlerTaskMapper;
import org.chen.ctrip.service.CrawlerTaskLogService;
import org.chen.ctrip.service.CrawlerTaskService;
import org.chen.ctrip.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.scheduling.support.CronExpression;

import java.time.LocalDateTime;
import java.util.List;

@Slf4j
@Service
public class CrawlerTaskServiceImpl extends ServiceImpl<CrawlerTaskMapper, CrawlerTask> implements CrawlerTaskService {

    @Autowired
    private ProductService productService;

    @Override
    public List<CrawlerTask> getActiveTasks() {
        QueryWrapper<CrawlerTask> wrapper = new QueryWrapper<>();
        wrapper.in("status", 1, 0); // 只获取活跃状态的任务
        wrapper.orderByDesc("create_time");
        return list(wrapper);
    }

    @Override
    public void stopAllActiveTasks() {
        this.update(
                null,
                new LambdaUpdateWrapper<CrawlerTask>()
                        .eq(CrawlerTask::getStatus, 1)
                        .set(CrawlerTask::getStatus, 2)
                        .set(CrawlerTask::getUpdateTime, LocalDateTime.now())
        );
    }

    @Override
    public CrawlerExecutionResult executeTaskWithResult(Long id) {
        CrawlerTask task = getById(id);
        if (task == null) {
            throw new RuntimeException("任务不存在: " + id);
        }

        CrawlerExecutionResult result = new CrawlerExecutionResult();
        result.setTaskId(String.valueOf(id));
        result.setTaskName(task.getTaskName());
        result.setKeywords(task.getKeywords());
        result.setStartPageIndex(task.getStartPageIndex());
        result.setEndPageIndex(task.getEndPageIndex());
        result.setPageSize(task.getPageSize());
        result.setDepartureCity(task.getDepartureCity());

        try {
            String[] keywords = task.getKeywords().split(",");
            StringBuilder executionDetail = new StringBuilder();
            boolean hasError = false;

            for (String keyword : keywords) {
                keyword = keyword.trim();
                if (!keyword.isEmpty()) {
                    try {
                        CrawlerExecutionResult keywordResult;

                        // 判断是单页还是页数范围爬取
                        if (task.getEndPageIndex() == null || task.getEndPageIndex().equals(task.getStartPageIndex())) {
                            // 单页爬取
                            int pageIndex = task.getStartPageIndex() != null ? task.getStartPageIndex() : 1;
                            CrawlResult crawlResult = productService.crawlProductsWithResult(keyword, pageIndex, task.getPageSize(), task.getDays(), task.getDepartureCity());

                            // 转换为TaskExecutionResult格式
                            keywordResult = new CrawlerExecutionResult();
                            keywordResult.setProductCount(crawlResult.getTotalCount());
                            keywordResult.setNewProductCount(crawlResult.getNewCount());
                            keywordResult.setUpdateProductCount(crawlResult.getUpdateCount());
                            keywordResult.setSuccess(crawlResult.isSuccess());
                            keywordResult.setTotalPages(1);
                            keywordResult.setSuccessPages(crawlResult.isSuccess() ? 1 : 0);
                            keywordResult.setFailedPages(crawlResult.isSuccess() ? 0 : 1);

                        } else {
                            // 页数范围爬取
                            int startPage = task.getStartPageIndex() != null ? task.getStartPageIndex() : 1;
                            keywordResult = productService.crawlProductsRange(keyword, startPage, task.getEndPageIndex(), task.getPageSize(), task.getDays(), task.getDepartureCity());
                        }

                        // 汇总结果
                        result.setProductCount(result.getProductCount() + keywordResult.getProductCount());
                        result.setNewProductCount(result.getNewProductCount() + keywordResult.getNewProductCount());
                        result.setUpdateProductCount(result.getUpdateProductCount() + keywordResult.getUpdateProductCount());
                        result.setTotalPages(result.getTotalPages() + keywordResult.getTotalPages());
                        result.setSuccessPages(result.getSuccessPages() + keywordResult.getSuccessPages());
                        result.setFailedPages(result.getFailedPages() + keywordResult.getFailedPages());

                        if (!keywordResult.isSuccess()) {
                            hasError = true;
                        }

                        executionDetail.append(String.format("关键词[%s]: 页数%d, 成功页数%d, 总计%d个, 新增%d个, 更新%d个; ",
                                keyword, keywordResult.getTotalPages(), keywordResult.getSuccessPages(),
                                keywordResult.getProductCount(), keywordResult.getNewProductCount(), keywordResult.getUpdateProductCount()));

                    } catch (Exception e) {
                        hasError = true;
                        log.error("执行关键词{}爬取失败: {}", keyword, e.getMessage());
                        executionDetail.append(String.format("关键词[%s]: 执行失败 - %s; ", keyword, e.getMessage()));
                    }
                }
            }

            result.setSuccess(!hasError);
            result.setExecutionDetail(executionDetail.toString());

        } catch (Exception e) {
            result.setSuccess(false);
            result.setErrorMessage(e.getMessage());
            result.setExecutionDetail("任务执行失败: " + e.getMessage());
            throw e;
        }

        return result;
    }

    @Override
    public LocalDateTime calculateNextRunTime(String cronExpression) {
        try {
            CronExpression cron = CronExpression.parse(cronExpression);
            return cron.next(LocalDateTime.now());
        } catch (Exception e) {
            return null;
        }
    }

    @Override
    public void updateStatus(Long id, int status) {
        this.update(
                null,
                new LambdaUpdateWrapper<CrawlerTask>()
                        .eq(CrawlerTask::getId, id)
                        .set(CrawlerTask::getStatus, status)
                        .set(CrawlerTask::getUpdateTime, LocalDateTime.now())
        );
    }
}